/******************************************************************************

    Copyright (C) 2006 Alessio Stalla (alessiostalla@gmail.com)

    This file is part of PrettyProlog.

    PrettyProlog is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    PrettyProlog is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PrettyProlog; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    See the file COPYING for further details.

 *****************************************************************************/

package prettyprolog.datatypes;

import java.io.Serializable;

/** A Term is a generic Prolog object. */
public interface Term extends Serializable {

    /** 
     * Applies the given Substitution to this Term.
     * @return the Term resulting from applying the Substitution subst
     * to this Term.
     */
    public Term apply(Substitution subst);

    /**
     * same as <code>isGround(true)</code>.
     * @return <code>true</code> if this Term is strictly ground,
     * <code>false</code> otherwise.
     */
    public boolean isGround();

    /**
     * Whether this term is ground.<br />
     * If <code>strict == true</code>, the Term is considered ground if it
     * doesn't contain any variables; else, this method returns
     * <code>true</code> also if this Term contains only anonymous and/or
     * temporary variables.
     * @return <code>true</code> if this Term is ground, <code>false</code>
     * otherwise.
     */
    public boolean isGround(boolean strict);
    
    /**
     * Makes a copy of this Term renaming variables to avoid name clashes.
     * @param vars a Substitution containing the mappings between
     * old variables and new ones. Consider copying <code>p(X, q(X))</code>:
     * <code>p.copy()</code> will exchange <code>X</code> with, say,
     * <code>_X123</code> and <code>q.copy()</code> must know this, or it'll
     * substitute <code>X</code> with another temporary variable. Note that
     * if the implementation of this method does itself substitute variables
     * it must update the Substitution accordingly.
     * @return the copy.
     */
    public Term copy(Substitution vars);
    
    /** Same as <code>contains(t, false)</code>. */
    public boolean contains(Term t); 
    
    /**
     * Whether <code>t</code> is contained in this Term.<br />
     * If this term has any subterms, this method returns
     * <code>true</code> if <code>t</code> is among them or,
     * if <code>deep == true</code>, if one of them contains
     * <code>t</code>.<br />
     * In every other case, this method returns <code>false</code>.<br />
     * Note that a Term should never contain itself.
     */
    public boolean contains(Term t, boolean deep);
    
}